#include <QtDebug>
#include <QMessageBox>
#include <QByteArray>
#include <QString>
#include <QTextDecoder>
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setFixedSize(530, 360);
    ui->baudRateBox->setCurrentIndex(3);

    m_serialPort = new QSerialPort();

    ui->sendBtn_1->setEnabled(false);
    ui->sendBtn_2->setEnabled(false);

    searchSerial();

#if defined(Q_OS_WIN)
    qDebug()<<"Q_OS_WIN";
#else
    qDebug()<<"Q_OS_other";
#endif
}

MainWindow::~MainWindow()
{
    if (m_serialPort->isOpen())
    {
        m_serialPort->close();
    }
    delete m_serialPort;

    delete ui;
}

void MainWindow::searchSerial()
{
    ui->portBox->clear();
    QStringList list;

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        qDebug()<<tr("serial port name:") << info.portName();
        QSerialPort serial;
        serial.setPort(info);
        if (serial.open(QIODevice::ReadWrite))
        {
           list << info.portName();
           serial.close();
        }
    }
#if defined(Q_OS_WIN)
    std::sort(list.begin(), list.end());
#else
    qSort(list.begin(), list.end());
#endif

    ui->portBox->addItems(list);
}

void MainWindow::sendData(QString stringData)
{
#if 0
    //删除字符串中的空格
    stringData.remove(QRegExp("\\s"));
    QByteArray sendBuff;
    for (int i=0; i<stringData.length(); i+= 2)
    {
        QString str = stringData.mid(i, 2);
        sendBuff.append(static_cast<char>(str.toInt(nullptr, 16)));
    }
    m_serialPort->write(sendBuff);
#else
    m_serialPort->write(stringData.toLatin1());
#endif
}

void MainWindow::openPort()
{
    if (m_serialPort->isOpen())
    {
        m_serialPort->clear();
        m_serialPort->close();
    }
    m_serialPort->setPortName(ui->portBox->currentText());
    if (!m_serialPort->open(QIODevice::ReadWrite)){
        //该串口无法打开
        qDebug()<<ui->portBox->currentText()<<tr(":")<<tr("该串口无法打开");
        QMessageBox().information(this, tr("Open port err"), tr("串口打开失败"));

        return ;
    }
    qDebug()<<tr("串口打开成功");

    m_serialPort->setBaudRate(ui->baudRateBox->currentText().toInt(), QSerialPort::AllDirections);
    m_serialPort->setDataBits(static_cast<QSerialPort::DataBits>(ui->dataBitBox->currentText().toInt()));
    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);

    switch(ui->checkBox->currentIndex())
    {
    case 0x00: m_serialPort->setParity(QSerialPort::NoParity);break;
    case 0x01: m_serialPort->setParity(QSerialPort::OddParity);break;
    case 0x02: m_serialPort->setParity(QSerialPort::EvenParity);break;
    case 0x03: m_serialPort->setParity(QSerialPort::MarkParity);break;
    case 0x04: m_serialPort->setParity(QSerialPort::SpaceParity);break;
    default: m_serialPort->setParity(QSerialPort::NoParity);break;
    }

    switch(ui->stopBitBox->currentIndex())
    {
    case 0x00: m_serialPort->setStopBits(QSerialPort::OneStop);break;
    case 0x01: m_serialPort->setStopBits(QSerialPort::OneAndHalfStop);break;
    case 0x02: m_serialPort->setStopBits(QSerialPort::TwoStop);break;
    default: m_serialPort->setStopBits(QSerialPort::OneStop);break;
    }

    m_serialPort->open(QIODevice::ReadWrite);
    connect(m_serialPort, &QSerialPort::readyRead, this, &MainWindow::receiveInfo);
}

void MainWindow::receiveInfo()
{
    QByteArray info = m_serialPort->readAll();

    if (info.isEmpty()){
        //如果为空数据，则直接去掉
        return ;
    }
    QString displayStr;
    if (ui->hexRadio->isChecked())
    {
        //将原窗口的值保存到该变量中
        displayStr = ui->textBrowser->toPlainText();
        QString tempStr = info.toHex().data();
        for (int i=0; i<tempStr.length(); i+= 2)
        {
             QString st = tempStr.mid(i, 2);
             displayStr += st + " ";
        }
        //重新设置窗体显示的值
        ui->textBrowser->setText(displayStr);
    }else{
        QTextCodec * codec = QTextCodec::codecForName("GBK");
        displayStr = codec->toUnicode(info);
        //追加到新的一行中
        ui->textBrowser->append(displayStr);
    }
    //将显示自动将显示滚动到底部
    ui->textBrowser->moveCursor(QTextCursor::End);
}

void MainWindow::on_searchBtn_clicked()
{
    ui->portBox->clear();
    searchSerial();
}

void MainWindow::on_openBtn_clicked()
{
    if (m_serialPort->isOpen())
    {
        m_serialPort->clear();
        m_serialPort->close();

        ui->portBox->setEnabled(true);
        ui->baudRateBox->setEnabled(true);
        ui->dataBitBox->setEnabled(true);
        ui->checkBox->setEnabled(true);
        ui->stopBitBox->setEnabled(true);
        ui->searchBtn->setEnabled(true);

        ui->sendBtn_1->setEnabled(false);
        ui->sendBtn_2->setEnabled(false);

        ui->openBtn->setText(tr("打开"));
        qDebug()<<tr("串口已关闭");

        return ;
    }

    openPort();
    if (m_serialPort->isOpen()){
        ui->portBox->setEnabled(false);
        ui->baudRateBox->setEnabled(false);
        ui->dataBitBox->setEnabled(false);
        ui->checkBox->setEnabled(false);
        ui->stopBitBox->setEnabled(false);
        ui->searchBtn->setEnabled(false);

        ui->sendBtn_1->setEnabled(true);
        ui->sendBtn_2->setEnabled(true);

        ui->openBtn->setText(tr("关闭"));
        qDebug()<<tr("串口已打开");
    }
}

void MainWindow::on_cleanBtn_clicked()
{
    ui->textBrowser->clear();
}

void MainWindow::on_sendBtn_1_clicked()
{
    if (ui->sendBuff_1->text().isEmpty()){
        return ;
    }

    if (ui->checkBox_2->checkState())
    {
        ui->textBrowser->clear();
    }
    qDebug()<<tr("send01:")<<ui->sendBuff_1->text();

    sendData(ui->sendBuff_1->text());
}

void MainWindow::on_sendBtn_2_clicked()
{
    if (ui->sendBuff_2->text().isEmpty()){
        return ;
    }

    //如果打开了，发送清除输出显示，则每次发送会清除输出显示窗口
    if (ui->checkBox_2->checkState())
    {
        ui->textBrowser->clear();
    }
    qDebug()<<tr("send02:")<<ui->sendBuff_1->text();
    sendData(ui->sendBuff_2->text());
}
